﻿#include"stdafx.h"
#ifdef LK_REFLECTION_
namespace LK
{
	namespace Reflection
	{
		PNamespaceNode::PNamespaceNode(ptr<String> const& name, weakptr<TypeLibrary> const& library, PNamespaceNode const&baseNode) :PDomainNode(library, baseNode, name){}
		PNamespaceNode PNamespaceNode::FindOrAddNamespace(ptr<String> const&name)const{ return Check()->FindOrAddNamespace(name); }
		PTypeNode PNamespaceNode::FindOrAddTypeNode(ptr<String> const&str,ptr<Type> const&t)const{ return Check()->FindOrAddTypeNode(str,t); }
		/**
		@brief 获取类型节点数组*/
		ptr<Collection::IArray<PTypeNode>> PNamespaceNode::GetTypeNodeArray()const { return Check()->GetTypeNodeArray(); }
		NamespaceNode::NamespaceNode(ptr<String> const& name, weakptr<TypeLibrary> const& library, PNamespaceNode const&baseNode)
			: DomainNode(library, baseNode, name){}
		/**
		@brief 获取类型节点数组*/
		ptr<Collection::IArray<PTypeNode>> NamespaceNode::GetTypeNodeArray()const
		{
			ptr<Collection::IArray<PTypeNode>>arr((index_t)0);
			ptr<Type> t = Type::Make<PTypeNode>();
			for (index_t i = 0; i < InnerNodes->size(); ++i)
			if (InnerNodes[i]->GetType() == t)arr->Append((PTypeNode&)(InnerNodes[i]));
			return arr;
		}
		PNamespaceNode NamespaceNode::FindOrAddNamespace(ptr<String> const&name)
		{
			if (name.IsNullOrEmpty())Throw<PInvalidArgumentException>(L"命名空间的名称不能为空");
			if (name.StartsWith(GetLibrary().GetSeparatorRef()))return GetLibrary().GetGlobleNamespaceRef().FindOrAddNamespace(name.Substring(GetLibrary().GetSeparatorRef().size()));
			PStringArray arr = name.Split(GetLibrary().GetSeparatorRef());//获取命名空间分隔
			PNamespaceNode p=this;
			for (index_t i = 0; i < arr->size(); ++i)
			{
				ptr<LibraryNode> x = p.GetInnerNodeByName(arr[i]);
				if (x==null)
					p = Convert<PNamespaceNode,ptr<LibraryNode>>::RefFrom(p.AddInnerNode(new NamespaceNode(arr[i])));
				else if (cast<PNamespaceNode>(x)==null)Throw<PReflectionException >(L"指定的命名空间路径跟现有其它类型子节点同名");
				else p = (PNamespaceNode&)x;
			}
			return p;
		}
		PTypeNode NamespaceNode::FindOrAddTypeNode(ptr<String> const& name,ptr<Type> const&t)
		{
			index_t i = name.LastIndexOf(GetLibrary().GetSeparatorRef());
			if (i>=0)
			{
				ptr<String> str = name.Substring(i+1);
				if (i == 0)return GetLibrary().GetGlobleNamespaceRef().FindOrAddTypeNode(str,t);
				return FindOrAddNamespace(name.Substring(0, i)).FindOrAddTypeNode(str,t);
			}
			PTypeNode node = cast<PTypeNode>(GetInnerNodeByName(name));
			if (node==null && t!=null)
			{
				node = new TypeNode(t, name);
				AddInnerNode(node);
				if (GetLibrary()!=null)GetLibrary()->SetTypeNodeByInfo(t, node);
			}
			return node;
		}
	}
}
#endif
